
// Color palette generation
// Use defineColorHSL to generate an 11 shade palette for a color.
// @include defineColorHSL(colorname, hue, saturation, lightness)
// @param colorname
//      Type: string
//      expects a CSS custom property name
// @param hue
//      Type: integer
//      expects an integer 0-255
// @param saturation
//      Type: percentage
//      expects a percentage 0-100%
// @param lightness
//      Type: percentage
//      expects a percentage 0-100%
// @returns 11 CSS Custom Properties available in :root
//      named colorname-0 through colorname-10
//      The HSL you provide in the parameters will be in the
//      middle of the range at colorname-5.
// @returns 11 CSS Classes using colorname prefixed with sakai-colorize
//      These classes set the background-color to colorname and
//      set the color to a value which will always pass WCAG AA 
//      guidelines. Color will be selected from the following,
//      whichever first passes the contrast requirement.
//            colorname-1
//            colorname-9
//            white
//            black
//
// Example usage 
//      @include defineColorHSL(--myschool-gray, 214, 3%, 55%);
// Returns CSS Custom Properties on :root
@use "sass:color";
@use "sass:math";

@mixin defineColorHSL($color, $hue, $saturation, $lightness){

  // $j used in the tint/shade functions to lighten or darken the color
  $j: 10;
  // $i used to append numbers at the end of the color names
  $i: 7;

  @while $i > 0 {
    #{$color}--lighter-#{$i}: tint-color(hsl($hue, $saturation, $lightness), $j);

    .sakai-colorize#{$color}--lighter-#{$i} {
      color: color-contrast(
        tint-color(hsl($hue, $saturation, $lightness), $j),
        shade-color(hsl($hue, $saturation, $lightness), 8),
        tint-color(hsl($hue, $saturation, $lightness), 8)
      );
      background-color: tint-color(hsl($hue, $saturation, $lightness), $j);
    }
    $j: $j - 1.5;
    $i: $i - 1;
  }

  #{$color}: hsl($hue, $saturation, $lightness);

  .sakai-colorize#{$color} {
    color: color-contrast(
      hsl($hue, $saturation, $lightness),
      shade-color(hsl($hue, $saturation, $lightness), 8),
      tint-color(hsl($hue, $saturation, $lightness), 8)
    );
    background-color: hsl($hue, $saturation, $lightness);
  }

  $j: 1;
  $i: 1;
  @while $i < 8 {
    #{$color}--darker-#{$i}: shade-color(hsl($hue, $saturation, $lightness), $j);

    .sakai-colorize#{$color}--darker-#{$i} {
      color: color-contrast(
        shade-color(hsl($hue, $saturation, $lightness), $j),
        shade-color(hsl($hue, $saturation, $lightness), 8),
        tint-color(hsl($hue, $saturation, $lightness), 8)
      );
      background-color: shade-color(hsl($hue, $saturation, $lightness), $j);
    }
    $j: $j + 1.5;
    $i: $i + 1;
  }

}

// SASS Color contrast
// See https://github.com/twbs/bootstrap/pull/30168 for reference

// A list of pre-calculated numbers of pow(($value / 255 + .055) / 1.055, 2.4). (from 0 to 255)
$_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 .0033 .0037 .004 .0044 .0048 .0052 .0056 .006 .0065 .007 .0075 .008 .0086 .0091 .0097 .0103 .011 .0116 .0123 .013 .0137 .0144 .0152 .016 .0168 .0176 .0185 .0194 .0203 .0212 .0222 .0232 .0242 .0252 .0262 .0273 .0284 .0296 .0307 .0319 .0331 .0343 .0356 .0369 .0382 .0395 .0409 .0423 .0437 .0452 .0467 .0482 .0497 .0513 .0529 .0545 .0561 .0578 .0595 .0612 .063 .0648 .0666 .0685 .0704 .0723 .0742 .0762 .0782 .0802 .0823 .0844 .0865 .0887 .0908 .0931 .0953 .0976 .0999 .1022 .1046 .107 .1095 .1119 .1144 .117 .1195 .1221 .1248 .1274 .1301 .1329 .1356 .1384 .1413 .1441 .147 .15 .1529 .1559 .159 .162 .1651 .1683 .1714 .1746 .1779 .1812 .1845 .1878 .1912 .1946 .1981 .2016 .2051 .2086 .2122 .2159 .2195 .2232 .227 .2307 .2346 .2384 .2423 .2462 .2502 .2542 .2582 .2623 .2664 .2705 .2747 .2789 .2831 .2874 .2918 .2961 .3005 .305 .3095 .314 .3185 .3231 .3278 .3325 .3372 .3419 .3467 .3515 .3564 .3613 .3663 .3712 .3763 .3813 .3864 .3916 .3968 .402 .4072 .4125 .4179 .4233 .4287 .4342 .4397 .4452 .4508 .4564 .4621 .4678 .4735 .4793 .4851 .491 .4969 .5029 .5089 .5149 .521 .5271 .5333 .5395 .5457 .552 .5583 .5647 .5711 .5776 .5841 .5906 .5972 .6038 .6105 .6172 .624 .6308 .6376 .6445 .6514 .6584 .6654 .6724 .6795 .6867 .6939 .7011 .7084 .7157 .7231 .7305 .7379 .7454 .7529 .7605 .7682 .7758 .7835 .7913 .7991 .807 .8148 .8228 .8308 .8388 .8469 .855 .8632 .8714 .8796 .8879 .8963 .9047 .9131 .9216 .9301 .9387 .9473 .956 .9647 .9734 .9823 .9911 1;

$white: #fff;
$black: #000;

@function color-contrast($background, $color-contrast-dark: $color-contrast-dark, $color-contrast-light: $color-contrast-light, $min-contrast-ratio: $min-contrast-ratio) {
  $foregrounds: $color-contrast-light, $color-contrast-dark, $white, $black;
  $max-ratio: 0;
  $max-ratio-color: null;

  @each $color in $foregrounds {
    $contrast-ratio: contrast-ratio($background, $color);
    @if $contrast-ratio > $min-contrast-ratio {
      @return $color;
    } @else if $contrast-ratio > $max-ratio {
      $max-ratio: $contrast-ratio;
      $max-ratio-color: $color;
    }
  }

  @warn "Found no color leading to #{$min-contrast-ratio}:1 contrast ratio against #{$background}…";

  @return $max-ratio-color;
}

@function contrast-ratio($background, $foreground: $color-contrast-light) {
  $l1: luminance($background);
  $l2: luminance(opaque($background, $foreground));

  @return if($l1 > $l2, math.div($l1 + .05, $l2 + .05), math.div($l2 + .05, $l1 + .05));
}

// Return WCAG2.0 relative luminance
// See https://www.w3.org/WAI/GL/wiki/Relative_luminance
// See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
@function luminance($color) {
  $rgb: (
    "r": color.channel($color, "red", $space: rgb),
    "g": color.channel($color, "green", $space: rgb),
    "b": color.channel($color, "blue", $space: rgb)
  );

  @each $name, $value in $rgb {
    $value: if(math.div($value, 255) < .03928, 
               math.div(math.div($value, 255), 12.92), 
               nth($_luminance-list, math.min(255, math.max(0, math.floor($value))) + 1));
    $rgb: map-merge($rgb, ($name: $value));
  }

  @return (map-get($rgb, "r") * .2126) + (map-get($rgb, "g") * .7152) + (map-get($rgb, "b") * .0722);
}

// Return opaque color
// opaque(#fff, rgba(0, 0, 0, .5)) => #808080
@function opaque($background, $foreground) {
  @return mix(rgba($foreground, 1), $background, opacity($foreground) * 100 * 1%);
}

// Request a color level
@function color-level($color: $primary, $level: 0) {
  $color-base: if($level > 0, $black, $white);
  $level: abs($level);

  @return mix($color-base, $color, $level * $theme-color-interval);
}

// Lighten a color
@function tint-color($color, $level) {
  @return mix(white, $color, $level * $theme-color-interval * 1%);
}

// Darken a color
@function shade-color($color, $level) {
  @return mix(black, $color, $level * $theme-color-interval * 1%);
}

// The contrast ratio to reach against white, to determine if color changes from "light" to "dark". Acceptable values for WCAG 2.0 are 3, 4.5 and 7.
// See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast
$min-contrast-ratio:   4.5 !default;
// Set a specific jump point for requesting color jumps
$theme-color-interval: 9 !default;

/* Base theme */
:root {
  --sakai-theme-color-interval: 9;
  --sakai-color-contrast-threshold: 60%;
  --sakai-theme-switch-ease: background-color 0.6s cubic-bezier(0.76, 0, 0.24, 1);

  --sakai-color-white: hsl(0, 0%, 100%);
  --sakai-color-black: hsl(0, 0%, 0%);
  @include defineColorHSL(--sakai-color-gray, 214, 3%, 55%);
  @include defineColorHSL(--sakai-color-blue, 203, 76%, 52%);
  @include defineColorHSL(--sakai-color-teal, 180, 100%, 30%);
  @include defineColorHSL(--sakai-color-gold, 50, 99%, 43%);
  @include defineColorHSL(--sakai-color-green, 147, 92%, 34%);
  @include defineColorHSL(--sakai-color-orange, 30, 93%, 44%);
  @include defineColorHSL(--sakai-color-purple, 240, 94%, 63%);
  @include defineColorHSL(--sakai-color-red, 357, 100%, 40%);
  @include defineColorHSL(--sakai-lessons-navy, 214, 100%, 20%);

  --bs-border-width: 1px;
  --bs-border-radius: 4px;
  --bs-border-color: var(--sakai-border-color);
}
